package com.cskaoyan.shopping.service.impl;

import com.alibaba.fastjson.JSON;
import com.cskaoyan.mall.commons.exception.ExceptionProcessorUtils;
import com.cskaoyan.mall.constant.ShoppingRetCode;
import com.cskaoyan.mall.dto.ClearCartItemRequest;
import com.cskaoyan.mall.dto.ClearCartItemResponse;
import com.cskaoyan.shopping.converter.CartItemConverter;
import com.cskaoyan.shopping.converter.ProductConverter;
import com.cskaoyan.shopping.dal.entitys.Item;
import com.cskaoyan.shopping.dal.persistence.ItemMapper;
import com.cskaoyan.shopping.dto.*;
import com.cskaoyan.shopping.service.ICartService;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RMap;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * @program: duolaimall
 * @description:
 * @author: Lexis
 * @create: 2022-05-19 23:03
 **/
@Slf4j
@Service
public class CartServiceImpl implements ICartService {

    @Autowired
    ItemMapper itemMapper;
    @Autowired
    RedissonClient redissonClient;

    @Autowired
    ProductConverter productConverter;


    @Override
    public CartListByIdResponse getCartListById(CartListByIdRequest request) {
        CartListByIdResponse response = new CartListByIdResponse();

        try {
            request.requestCheck();
            List<SortCartProduct> sortCartProducts = new ArrayList<>();
            RMap<Object, Object> map = redissonClient.getMap(request.getUserId().toString());
            Collection<Object> values = map.values();
            for (Object value : values) {
                sortCartProducts.add((SortCartProduct) value);
            }
            sortCartProducts.sort(new Comparator<SortCartProduct>() {
                @Override
                public int compare(SortCartProduct o1, SortCartProduct o2) {
                    long l = o1.getAddTime().getTime() - o2.getAddTime().getTime();
                    if (l > 0) {
                        return -1;
                    } else if (l < 0) {
                        return 1;
                    } else {
                        return 0;
                    }
                }
            });
            List<CartProductDto> cartProductDtos = productConverter.sortCartProductsToDtos(sortCartProducts);
            response.setCartProductDtos(cartProductDtos);
            response.setCode(ShoppingRetCode.SUCCESS.getCode());
            response.setMsg(ShoppingRetCode.SUCCESS.getMessage());
        } catch (Exception e) {
            e.printStackTrace();
            ExceptionProcessorUtils.wrapperHandlerException(response, e);
        }
        return response;
    }

    @Override
    public AddCartResponse addToCart(AddCartRequest request) {
        AddCartResponse addCartResponse = new AddCartResponse();
        try {
            request.requestCheck();


            RMap<Object, Object> map = redissonClient.getMap(request.getUserId().toString());
            // 判断redis中是否已存在该商品
            SortCartProduct product = (SortCartProduct) map.get(request.getItemId().toString());
            if (product != null) {
                Long num = product.getProductNum();
                product.setProductNum(num + request.getNum());
                product.setAddTime(new Date());
                map.put(request.getItemId().toString(), product);
            } else {
                Item item = itemMapper.selectByPrimaryKey(request.getItemId());
                CartProductDto cartProductDto = CartItemConverter.item2Dto(item);
                cartProductDto.setChecked("true");
                cartProductDto.setProductNum(Long.valueOf(request.getNum()));
                SortCartProduct sortCartProduct = new SortCartProduct(cartProductDto, new Date());
                map.put(request.getItemId().toString(), sortCartProduct);
            }

            addCartResponse.setCode(ShoppingRetCode.SUCCESS.getCode());
            addCartResponse.setMsg(ShoppingRetCode.SUCCESS.getMessage());
        } catch (Exception e) {
            e.printStackTrace();
            ExceptionProcessorUtils.wrapperHandlerException(addCartResponse, e);
        }
        return addCartResponse;
    }

    @Override
    public UpdateCartNumResponse updateCartNum(UpdateCartNumRequest request) {
        UpdateCartNumResponse response = new UpdateCartNumResponse();

        try {
            request.requestCheck();
            RMap<Object, Object> map = redissonClient.getMap(request.getUserId().toString());
            SortCartProduct product = (SortCartProduct) map.get(request.getItemId().toString());
            product.setProductNum(Long.valueOf(request.getNum()));
            product.setChecked(request.getChecked());
            map.put(request.getItemId().toString(), product);
            response.setCode(ShoppingRetCode.SUCCESS.getCode());
            response.setMsg(ShoppingRetCode.SUCCESS.getMessage());
        } catch (Exception e) {
            e.printStackTrace();
            ExceptionProcessorUtils.wrapperHandlerException(response, e);
        }
        return response;
    }

    @Override
    public CheckAllItemResponse checkAllCartItem(CheckAllItemRequest request) {
        CheckAllItemResponse response = new CheckAllItemResponse();

        try {
            request.requestCheck();
            RMap<Object, Object> map = redissonClient.getMap(request.getUserId().toString());
            Collection<Object> values = map.values();
            for (Object value : values) {
                SortCartProduct item = (SortCartProduct) value;
                if (!request.getChecked().equals(item.getChecked())) {
                    item.setChecked(request.getChecked());
                    map.put(item.getProductId().toString(), item);
                }
            }
            response.setCode(ShoppingRetCode.SUCCESS.getCode());
            response.setMsg(ShoppingRetCode.SUCCESS.getMessage());
        } catch (Exception e) {
            e.printStackTrace();
            ExceptionProcessorUtils.wrapperHandlerException(response, e);
        }
        return response;
    }

    @Override
    public DeleteCartItemResponse deleteCartItem(DeleteCartItemRequest request) {
        DeleteCartItemResponse response = new DeleteCartItemResponse();
        try {
            request.requestCheck();
            RMap<Object, Object> map = redissonClient.getMap(request.getUserId().toString());
            map.remove(request.getItemId().toString());
            response.setCode(ShoppingRetCode.SUCCESS.getCode());
            response.setMsg(ShoppingRetCode.SUCCESS.getMessage());
        } catch (Exception e) {
            e.printStackTrace();
            ExceptionProcessorUtils.wrapperHandlerException(response, e);
        }
        return response;
    }

    @Override
    public DeleteCheckedItemResposne deleteCheckedItem(DeleteCheckedItemRequest request) {
        DeleteCheckedItemResposne resposne = new DeleteCheckedItemResposne();

        try {
            request.requestCheck();
            RMap<Object, Object> map = redissonClient.getMap(request.getUserId().toString());
            Collection<Object> values = map.values();
            for (Object value : values) {

                SortCartProduct item = (SortCartProduct) value;
                if ("true".equals(item.getChecked())) {
                    map.remove(item.getProductId().toString());
                }
            }
            resposne.setCode(ShoppingRetCode.SUCCESS.getCode());
            resposne.setMsg(ShoppingRetCode.SUCCESS.getMessage());
        } catch (Exception e) {
            e.printStackTrace();
            ExceptionProcessorUtils.wrapperHandlerException(resposne, e);
        }
        return resposne;
    }

    @Override
    public ClearCartItemResponse clearCartItemByUserID(ClearCartItemRequest request) {
        ClearCartItemResponse response = new ClearCartItemResponse();

        try {
            request.requestCheck();
            RMap<Object, Object> map = redissonClient.getMap(request.getUserId().toString());
            for (Long productId : request.getProductIds()) {
                map.remove(productId.toString());
            }
            response.setCode(ShoppingRetCode.SUCCESS.getCode());
            response.setMsg(ShoppingRetCode.SUCCESS.getMessage());
        } catch (Exception e) {
            e.printStackTrace();
            ExceptionProcessorUtils.wrapperHandlerException(response, e);
        }
        return response;
    }
}
